<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Meta Filtering</title>
</head>

<body>

<h2>Meta Matchers</h2>

<p>One of the principal use cases for defining <a
	href="meta-info.html">meta info</a> in our stories is to be able to
filter the stories based on the meta info provided.</p>

<p>A meta filter is represented as a string and supports multiple meta matcher languages based on the prefix used:</p>

<ul>
<li>default meta matcher:  activated if no known prefix is found</li>
<li>groovy meta matcher: needs to prefixed by <b>groovy:</b></li>
</ul>

<h3>Default Meta Matcher</h3>

<p>The default meta matcher has a very simple language structure that mirrors that of the meta
properties, expressed as a sequence of name-value patterns:</p>
<pre class="brush: plain">
   default meta matcher :== ([+|-] [name] [value pattern])+
</pre>
<p>where <b>[+|-]</b> indicates if the filter should include or
exclude the meta property and the <b>[value pattern]</b> can be either
an exact match of the property value (including empty value) or use the
<b>*</b> matching notation.</p>

<p>The following are all valid meta matchers:</p>
<pre class="brush: plain">
   +author Mauro
   +theme filtering
   +author * +theme filtering
   +author * +theme filtering -skip
   -skip
</pre>

<p>A few examples of meta matchers and properties that matched or not:
<table class="bodyTable">
<thead><th>Meta Matcher</th><th>Meta Property</th><th>Matched</th></thead>
<tbody>
<tr class="a"><td>+theme smoke testing -skip</td><td>@theme smoke testing</td><td>true</td></tr>
<tr class="b"><td>+theme smoke testing -skip</td><td>@skip</td><td>false</td></tr>
<tr class="a"><td>+theme smoke testing</td><td>@theme smoke testing</td><td>true</td></tr>
<tr class="b"><td>+theme smoke testing</td><td>@theme testing</td><td>false</td></tr>
<tr class="a"><td>-skip</td><td>@theme testing</td><td>true</td></tr>
<tr class="b"><td>-skip</td><td>@skip</td><td>false</td></tr>
<tr class="a"><td>+theme smoke testing -theme UI</td><td>@theme smoke testing</td><td>true</td></tr>
<tr class="b"><td>+theme smoke testing -theme UI</td><td>@theme UI</td><td>false</td></tr>
</tbody>
</table>
</p>

<h3>Groovy Meta Matcher</h3>

<p>The Groovy meta matcher allows the logic of the matching to be expressed in Groovy using the values of the meta property names and values:</p>

<p>The following are all valid meta matchers (excluding the "groovy:" prefix):</p>
<pre class="brush: plain">
   author == 'Mauro'
   !skip
   theme == 'filtering' && theme != 'smoke testing' 
   theme ==~ /.*[testing|regression].*/
</pre>

<span class="followup">As Groovy is an optional dependency, users wanting to use the Groovy Meta Matcher need to 
add it to the runtime classpath.  If using Maven, you need to define Groovy as a Plugin dependency, c.f. <a href="maven-goals.html">Maven goals</a>.
</span>

<h3>Custom Meta Matchers</h3>

<p>Custom meta matcher instances can also be provided to the <a href="javadoc/core/org/jbehave/core/embedder/Embedder.html">Embedder</a> as a map, indexed by the prefix used in the filter content:</p>
 
<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
 Map<String, MetaMatcher> customMatchers = new HashMap<String, MetaMatcher>();
 customMatchers.put("ruby:", new RubyMetaMatcher());
 embedder.useMetaMatchers(customMatchers);
]]>
</script>
<p>
The filter content will then need to start by the same prefix defined in the map:
</p>
<pre class="brush: plain">
    ruby: # some ruby matching code
</pre>

<p>
Custom instances that are matched by the prefix of the filter content will take precedence over the Groovy or default matchers.
</p>

<span class="followup">Users wanting to use a custom Meta Matcher need to add to the runtime classpath any dependencies required by the 
implementation of the matcher.  If using Maven, you need to define them as a Plugin dependency, c.f. <a href="maven-goals.html">Maven goals</a>.
</span>

<h2>Filtering on Story and Scenario Elements</h2>

<p>In addition to the <a href="meta-info.html">meta info</a> that is defined by the user, both at story and scenario level, JBehave also 
exposes the top-level elements of stories and scenarios, which can be filtered on.  These include: 
<ul>
<li>story: path, description and narrative</li>
<li>scenario: title, givenStories and examplesTable</li>
</ul>
The meta properties are exposed by default with no prefix, but can be configured to have one via the configuration 
<a href="javadoc/core/org/jbehave/core/embedder/StoryControls.html">StoryControls</a>:
</p>
<pre class="brush: java">
configuration.storyControls().useStoryMetaPrefix("story_").useScenarioMetaPrefix("scenario_");
</pre>

<h2>Filtering on Example Scenarios</h2>

<p>Meta info can also be specified to filter the example scenarios to be run:</p>
<pre class="brush: bdd">
Scenario:  A scenario with filtering on examples

Meta:  @os 

Given an operating system [value]

Examples:
|Meta:|value|
|@os Linux|Ubuntu|
|@os Unix|OS X| 
</pre>

<p>To activate meta-filtering on example scenarios, add a column <b>Meta:</b> (or equivalent Meta keyword in your language locale).
If the meta info in a given row of the column is matched by the meta filter, the corresponding scenario is run.
</p>

<span class="followup">Note that because the meta filter is unique, this must also match the containing scenario or story. 
For example, if the rows are filtered on a meta property value, this can be ensured by the presence of the property name (without value) at the scenario level.</span>

<h2>Configuring Meta Filters</h2>

<p>As usual, JBehave allow multiple equivalent ways of
configuration. One can specify the meta filters directly via the
Embedder, either programmatically or via the annotation:</p>

<pre class="brush: java">
Embedder embedder = ... // define as required
embedder.useMetaFilters(asList("+author Mauro", "+theme filtering", "-skip"));
</pre>

<pre class="brush: java">
@RunWith(AnnotatedEmbedderRunner.class)
@UsingEmbedder(metaFilters = {"+author Mauro", "+theme filtering", "-skip"})
public class AnnotatedTraderEmbedder extends InjectableEmbedder {
}
</pre>

<p>The meta filters can also be specified via <a
    href="ant-tasks.html">Ant tasks</a> or <a href="maven-goals.html">Maven
goals</a>, using the "metaFilters" attribute or configuration element.</p>

<span class="followup">Note that because of its additive
sequential nature, the meta filters will all be joined together when
running the stories. Have different meta filters comes into play when
doing <a href="story-mapping.html">story mapping</a>.</span>

<div class="clear">
<hr />
</div>

</body>
</html>
